package top.broncho.mvvm.base

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.jetbrains.anko.AnkoLogger
import top.broncho.gank.bean.HttpResult
import top.broncho.gank.http.exception.ErrorStatus

abstract class BaseViewModel(val app: Application) : AndroidViewModel(app), AnkoLogger {
    fun launchUI(block: suspend CoroutineScope.() -> Unit) = viewModelScope.launch { block() }

    /**
     * 过滤请求结果，其他全抛异常
     * @param block 请求体
     * @param success 成功回调
     * @param error 失败回调
     * @param complete  完成回调（无论成功失败都会调用）
     */
    fun <T> launchOnlyResult(
        block: suspend CoroutineScope.() -> HttpResult<T>,
        success: (T) -> Unit,
        error: (Throwable) -> Unit = {},
        complete: () -> Unit = {}
    ) = launchUI {
        try {
            val response = block()
            if (response.errorCode == ErrorStatus.SUCCESS) {
                success(response.data)
            } else {
                error(Throwable(response.errorMsg))
            }
        } catch (e: Throwable) {
            error(e)
        } finally {
            complete()
        }
    }

    fun <T> launchResult(
        block: suspend CoroutineScope.() -> HttpResult<T>,
        success: (T?) -> Unit,
        error: (Throwable) -> Unit = {},
        complete: () -> Unit = {}
    ) = launchUI {
        try {
            val response = block()
            if (response.errorCode == ErrorStatus.SUCCESS) {
                success(response.data)
            } else {
                error(Throwable(response.errorMsg))
            }
        } catch (e: Throwable) {
            error(e)
        } finally {
            complete()
        }
    }
}